package net.mayee.alice.filter.antisamy;

import org.owasp.validator.html.AntiSamy;
import org.owasp.validator.html.CleanResults;
import org.owasp.validator.html.Policy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class AntisamyFilter implements Filter {

    private final Logger LOGGER = LoggerFactory.getLogger(AntisamyFilter.class);
    private final String POLICY_FILE_LOCATION = "/WEB-INF/xml/antisamy-alice-1.0.0.xml";

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @SuppressWarnings("unchecked")
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        Map m = request.getParameterMap();
        try {
            m = this.clearRequestPra((HttpServletRequest) request,
                    new HashMap());
        } catch (Exception e) {
            LOGGER.error("**** AntisamyFilter -> doFilter fail! ****", e);
        }
        ParameterRequestWrapper wrapRequest = new ParameterRequestWrapper(
                ((HttpServletRequest) request), m);
        chain.doFilter(wrapRequest, response);
    }

    @Override
    public void destroy() {
    }

    @SuppressWarnings("unchecked")
    private Map clearRequestPra(HttpServletRequest request, Map m) {
        Map params = request.getParameterMap();
        String path = request.getSession().getServletContext().getRealPath("/");

        Policy policy;
        AntiSamy as = new AntiSamy();
        try {
            policy = Policy.getInstance(path + POLICY_FILE_LOCATION);

            Set<String> keys = params.keySet();
            for (String key : keys) {
                Object value = params.get(key);
                if (value instanceof String[]) {
                    String[] str = (String[]) value;
                    int i = 0;
                    for (String v : (String[]) value) {
                        CleanResults cr = as.scan(v, policy);
                        str[i] = new String(cr.getCleanHTML());
                        i++;
                    }
                    m.put(key, str);
                } else {
                    m.put(key, value);
                }
            }
        } catch (Exception e) {
            LOGGER.error("**** AntisamyFilter -> clearRequestPra fail! ****", e);
        }

        return m;
    }

    private String scan(String content) {
        String cleanHtml = "";
        try {
            Policy policy = Policy.getInstance(POLICY_FILE_LOCATION);
            AntiSamy as = new AntiSamy();
            CleanResults cr = as.scan(content, policy);
            cleanHtml = cr.getCleanHTML();
        } catch (Exception e) {
            LOGGER.error("**** AntisamyFilter -> scan fail! ****", e);
        }
        return cleanHtml;
    }

}
